﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;

namespace ThinkAway.Plus.Office
{
    public partial class FrmMain : Form
    {
        private bool _canceled;

        private string _outputPath;

        private string _ext = ".pdf";

        private readonly List<string> _inputFiles;

        private readonly IOfficeFormatConvert _officeFormatConvert;

        public FrmMain(string[] commandLineArgs)
        {
            InitializeComponent();

            _inputFiles = new List<string>();

            _officeFormatConvert = new OfficeFormatConvert();

            _officeFormatConvert.ProgressChanged += (sender, args) =>
                                                        {
                                                            try
                                                            {
                                                                if (InvokeRequired)
                                                                {
                                                                    Invoke(
                                                                        new EventHandler<ProgressChangeArgs>(
                                                                            OfficeFormatConvertProgressChanged), sender,
                                                                        args);
                                                                }
                                                            }
                                                            catch (Exception exception)
                                                            {
                                                                Console.WriteLine(exception);
                                                            }
                                                        };

            if(commandLineArgs.Length > 0)
            {
                string command = commandLineArgs[0];
                switch (command)
                {
                    case "/r":
                        RegistryContextMenu();
                        break;
                    default:
                        foreach (string fileName in commandLineArgs)
                        {
                            AddToListView(fileName);
                            _outputPath = Path.GetDirectoryName(fileName);
                        }
                        break;
                }
            }
        }

        void OfficeFormatConvertProgressChanged(object sender, ProgressChangeArgs args)
        {
            progressBar1.Maximum = args.Length;
            progressBar1.Value = args.Current;


            lblProgress.Text = string.Format("{0}/{1}", args.Current, args.Length);

            switch (args.Mode)
            {
                case OfficeFormatConvertStatus.Opening:
                    listView1.Items[args.Current - 1].SubItems[2].Text = "Opening";
                    lblStatusText.Text = string.Format("Opening file: {0}", args.FileName);
                    break;
                case OfficeFormatConvertStatus.Convert:
                    listView1.Items[args.Current - 1].SubItems[2].Text = "Convert";
                    lblStatusText.Text = string.Format("Convert file: {0}", args.FileName);
                    //progressBar1.Style = ProgressBarStyle.Marquee;
                    break;
                case OfficeFormatConvertStatus.Complate:
                    listView1.Items[args.Current - 1].SubItems[2].Text = "Completed";
                    lblStatusText.Text = string.Format("Completed file: {0}", args.FileName);
                    //progressBar1.Style = ProgressBarStyle.Blocks;
                    break;
                case OfficeFormatConvertStatus.AllComplate:
                    lblStatusText.Text = "Completed .";
                    break;
            }
        }
        private void BtnBrowserClick(object sender, System.EventArgs e)
        {
            var folderBrowser = new FolderBrowserDialog { ShowNewFolderButton = false };
            DialogResult showDialog = folderBrowser.ShowDialog(this);
            if (showDialog == DialogResult.OK)
            {
                var directory = new DirectoryInfo(folderBrowser.SelectedPath);
                FileInfo[] fileInfos = directory.GetFiles("*.doc?");
                foreach (FileInfo fileInfo in fileInfos)
                {
                    AddToListView(fileInfo.FullName);
                }
            }
        }

        private void AddToListView(string fileName)
        {
            _inputFiles.Add(fileName);

            var item = new ListViewItem { Text = Path.GetFileNameWithoutExtension(fileName) };
            item.SubItems.Add(fileName);
            item.SubItems.Add("Ready.");
            item.Tag = fileName.GetHashCode();
            listView1.Items.Add(item);
        }

        private void BtnFileClick(object sender, EventArgs e)
        {
            var openFile = new OpenFileDialog { Filter = "All Office Document|*.doc;*.docx;*.wps", Multiselect = true };
            DialogResult showDialog = openFile.ShowDialog(this);
            if (showDialog == DialogResult.OK)
            {
                foreach (string fileName in openFile.FileNames)
                {
                    AddToListView(fileName);
                }
            }
            else
            {
                _canceled = true;
            }
        }

        private void BtnOutputClick(object sender, System.EventArgs e)
        {
            var folderBrowser = new FolderBrowserDialog();
            DialogResult showDialog = folderBrowser.ShowDialog(this);
            if (showDialog == DialogResult.OK)
            {
                _outputPath = folderBrowser.SelectedPath;
            }
            else
            {
                _canceled = true;
            }
        }

        private void BtnConvertClick(object sender, EventArgs e)
        {
            _canceled = false;
            if (_inputFiles.Count == 0)
            {
                BtnFileClick(sender, e);
                if (!_canceled) BtnConvertClick(sender, e);
                return;
            }
            if (string.IsNullOrEmpty(_outputPath))
            {
                BtnOutputClick(sender, e);
                if (!_canceled) BtnConvertClick(sender, e);

                return;
            }
            //convert all doc files to pdf.
            string[] inputFiles = _inputFiles.ToArray();
            var outputList = new List<string>(inputFiles.Length);
            foreach (string inputFile in inputFiles)
            {
                string fileName = Path.GetFileNameWithoutExtension(inputFile);
                outputList.Add(Path.Combine(_outputPath, string.Format("{0}{1}", fileName, _ext)));
            }
            string[] outputFiles = outputList.ToArray();
            var thread = new Thread(() => _officeFormatConvert.Convert(inputFiles, outputFiles));
            thread.Start();
        }

        private void PbxKingsoftClick(object sender, EventArgs e)
        {
             var pbx =  sender as PictureBox;
             if(pbx.Name == pbxKingsoft.Name)
             {
                 Process.Start("http://www.kingsoft.com");
             }
             else if(pbx.Name == pbxKSO.Name)
             {
                 Process.Start("http://www.wps.cn");
             }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            lblTitle.Cursor = Cursors.Hand;

            pbxKSO.Cursor = Cursors.Hand;
            pbxKingsoft.Cursor = Cursors.Hand;
        }

        public void RegistryContextMenu()
        {
            try
            {
                RegistryKey rootReg = Registry.ClassesRoot;
                RegistryKey myReg = rootReg.CreateSubKey(string.Format(@"*\shell\{0}", ProductName));
                if (myReg != null)
                {
                    myReg.SetValue(null, ProductName);
                    RegistryKey commandReg = rootReg.CreateSubKey(string.Format(@"*\shell\{0}\command", ProductName));
                    if (commandReg != null)
                    {
                        commandReg.SetValue(null, string.Format("{0} \"%1\"", Application.ExecutablePath));
                        commandReg.Close();
                    }
                    myReg.Close();
                }
                rootReg.Close();
            }
            catch (Exception)
            {
                MessageBox.Show(this, "Please use the Run as administrator.");
            }
        }

        private void lblTitle_Click(object sender, EventArgs e)
        {
            Process.Start(string.Format("http://lsong.org/product/{0}?version={1}", ProductName,ProductVersion));
        }

        private void listView1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                    case Keys.Delete:
                    foreach (ListViewItem item in listView1.SelectedItems)
                    {
                        _inputFiles.Remove(item.SubItems[1].Text);
                        listView1.Items.Remove(item);
                    }
                    break;
            }
        }

        private void listView1_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.All;
            
        }

        private void listView1_DragDrop(object sender, DragEventArgs e)
        {
            IDataObject dataObject = e.Data;
            bool dataPresent = dataObject.GetDataPresent(DataFormats.FileDrop, false);
            if(dataPresent)
            {
                string[] fileNames = (string[]) dataObject.GetData(DataFormats.FileDrop, false);
                foreach (var fileName in fileNames)
                {
                    AddToListView(fileName);
                    _inputFiles.Add(fileName);
                }
            }
        }

        private void listView1_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.All;
        }

        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            ToolStripMenuItem toolStripMenuItem = (ToolStripMenuItem) e.ClickedItem;
            switch (e.ClickedItem.Name)
            {
                case "menuDOC":
                    _ext = ".doc";
                    break;
                case "menuPDF":
                    _ext = ".pdf";
                    break;
                case "menuTXT":
                    _ext = ".txt";
                    break;
            }

            menuDOC.Checked = false;
            menuPDF.Checked = false;
            menuTXT.Checked = false;
            toolStripMenuItem.Checked = true;
        }
    }
}
